﻿/**************************************************************
 *
 * 唯一标识：8ef3fab8-99ea-4046-88fb-439f619230a5
 * 命名空间：Sgr.Trackers.Domain
 * 创建时间：2024/7/17 18:29:45
 * 机器名称：DESKTOP-HJ4OAG9
 * 创建者：CocoYuan
 * 电子邮箱：fengqinhua2016@163.com
 * 描述：
 *
 **************************************************************/

using Microsoft.EntityFrameworkCore;
using Sgr.Domain.Repositories;

namespace Sgr.Trackers.Domain
{
    public interface IMessageTrackerLogRepository : IRepository<MessageTrackerLog>
    {
        /// <summary>
        /// 尝试将指定消息标记为“已处理”。
        /// 通过向幂等表 sgr_message_trackerlog 插入一条记录（主键为 sgr_id）实现幂等控制。
        ///
        /// 如果插入成功，表示该消息之前未处理；
        /// 如果插入失败（如唯一键冲突，表示该消息已处理过），将抛出 DbUpdateException。
        ///
        /// 通常，本方法应与业务逻辑一起包裹在同一个事务中，由调用方统一处理异常与幂等逻辑。
        /// </summary>
        /// <param name="messageId">消息唯一标识</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>无返回值</returns>
        /// <exception cref="DbUpdateException">插入失败时可能抛出，如唯一键冲突或数据库错误</exception>
        Task MarkAsProcessedAsync(string messageId, CancellationToken cancellationToken = default);

        /// <summary>
        /// 清理早于指定时间的已处理消息记录，以控制表数据量，提升存储与查询效率。
        ///
        /// 本方法会查找所有 ProcessedOnUtc 字段早于 olderThanUtc 的记录，
        /// 按处理时间升序排序（最早处理的优先删除），并删除最多 max 条记录。
        ///
        /// 使用 EF Core 的 ExecuteDeleteAsync 实现高效批量删除，不查询实体到内存，
        /// 性能高，适合定期清理任务（如定时 Job）。
        /// </summary>
        /// <param name="olderThanUtc">
        /// 清理阈值时间（UTC）。所有 ProcessedOnUtc 字段值早于该时间的记录将被视为可清理。
        /// </param>
        /// <param name="max">
        /// 单次清理的最大记录条数，用于控制单次操作的影响范围，避免误删过多数据。
        /// 取值范围会被自动限制在 [1, 2000]，即：
        /// - 若 max 小于等于 0，则不执行任何清理，直接返回 0；
        /// - 若 max 大于 2000，则自动按 2000 处理。
        /// </param>
        /// <param name="cancellationToken">用于取消清理操作的令牌</param>
        /// <returns>
        /// 实际删除的记录条数。如果未执行删除（如参数无效或无符合条件的数据），则返回 0。
        /// </returns>
        Task<int> CleanupAsync(DateTime olderThanUtc, int max, CancellationToken cancellationToken = default);
    }
}